package com.sdkj.fixed.asset.hc.service;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.sdkj.fixed.asset.api.hc.vo.in.IdParams;
import com.sdkj.fixed.asset.api.hc.vo.in.StatisticsParams;
import com.sdkj.fixed.asset.api.hc.vo.out.CategotryProduct;
import com.sdkj.fixed.asset.api.hc.vo.out.ProductStatistics;
import com.sdkj.fixed.asset.common.base.*;
import com.sdkj.fixed.asset.common.exception.LogicException;
import com.sdkj.fixed.asset.common.utils.ObjectUtil;
import com.sdkj.fixed.asset.hc.mapper.*;
import com.sdkj.fixed.asset.hc.mapper.ProductMapper;
import com.sdkj.fixed.asset.hc.pojo.ProductImport;
import com.sdkj.fixed.asset.pojo.hc.*;
import com.sdkj.fixed.asset.pojo.hc.Product;
import com.sdkj.fixed.asset.pojo.system.OrgManagement;
import com.sdkj.fixed.asset.pojo.system.UsageManagement;
import com.sdkj.fixed.asset.pojo.system.UserManagement;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import sun.rmi.runtime.Log;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/***
 *
 * @author scx
 *
 */
@Service
public class ProductService extends BaseService<Product> {

    @Resource
    private ProductMapper mapper;

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private ProductTypeMapper productTypeMapper;

    @Resource
    private ReceiptInProductMapper receiptInProductMapper;

    @Resource
    private ReceiptOutProductMapper receiptOutProductMapper;

    @Resource
    private ReceiptSetProductMapper receiptSetProductMapper;

    @Resource
    private ReceiptMoveProductMapper receiptMoveProductMapper;

    @Override
    public BaseMapper<Product> getMapper() {
        return mapper;
    }

    @Resource
    private CategoryProductMapper categoryProductMapper;

    @Resource
    private OrgManagementMapper orgManagementMapper;

    @Resource
    private UserManagementMapper userManagementMapper;

    @Resource
    private QwertMapper qwertMapper;

    @Resource
    private ReceiptMoveMapper receiptMoveMapper;

    /**
     * 校验code
     *
     * @param entity 产品
     * @param flag   新增/修改
     */
    private void checkCode(Product entity, Boolean flag) {
        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("code", entity.getCode());
        criteria.andEqualTo("type", entity.getType());
        criteria.andNotEqualTo("state", 3);
        if (flag) {
            criteria.andNotEqualTo("id", entity.getId());
        }
        if (0 != mapper.selectByExample(example).size()) {
            throw new LogicException("编码已存在");
        }
    }

    /**
     * 校验name
     *
     * @param entity 产品
     * @param flag   新增/修改
     */
    private void checkName(Product entity, Boolean flag) {
        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("name", entity.getName());
        criteria.andEqualTo("type", entity.getType());
        criteria.andNotEqualTo("state", 3);
        if (flag) {
            criteria.andNotEqualTo("id", entity.getId());
        }
        if (0 != mapper.selectByExample(example).size()) {
            throw new LogicException("名称已存在");
        }
    }

    /**
     * 校验入库单
     *
     * @param product 产品
     */
    private void checkReceiptIn(Product product) {
        Example example = new Example(ReceiptInProduct.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productId", product.getId());
        if (receiptInProductMapper.selectByExample(example).size() != 0) {
            throw new LogicException("物品有相关入库单不能删除");
        }
    }

    /**
     * 校验出库单
     *
     * @param product 产品
     */
    private void checkReceiptOut(Product product) {
        Example example = new Example(ReceiptOutProduct.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productId", product.getId());
        if (receiptOutProductMapper.selectByExample(example).size() != 0) {
            throw new LogicException("物品有相关出库单不能删除");
        }
    }

    /**
     * 校验调拨单
     *
     * @param product 产品
     */
    private void checkReceiptMove(Product product) {
        Example example = new Example(ReceiptMoveProduct.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productId", product.getId());
        if (receiptMoveProductMapper.selectByExample(example).size() != 0) {
            throw new LogicException("物品有相关调拨单不能删除");
        }
    }

    /**
     * 校验调整单
     *
     * @param product 产品
     */
    private void checkReceiptSet(Product product) {
        Example example = new Example(ReceiptSetProduct.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productId", product.getId());
        if (receiptSetProductMapper.selectByExample(example).size() != 0) {
            throw new LogicException("物品有相关库存调整单不能删除");
        }
    }
    /*****************************************************************************************************************************************/

    /**
     * 新增
     *
     * @param entity 产品
     * @return Product
     */
    public Product add(Product entity) {

        productTotalNum(entity.getOrgId());
        //code唯一
        checkCode(entity, false);
        //name唯一
        checkName(entity, false);
        mapper.insertSelective(entity);
        return entity;
    }

    /**
     * 修改
     *
     * @param entity 产品
     * @return Product
     */
    public Product edit(Product entity) {
        //code唯一
        checkCode(entity, true);
        //name唯一
        checkName(entity, true);
        mapper.updateByPrimaryKeySelective(entity);
        return entity;
    }

    /**
     * 删除
     *
     * @param entity 产品
     * @return Product
     */
    public Product del(Product entity) {
        Product product = mapper.selectByPrimaryKey(entity.getId());
        //检查有没有入库单
        checkReceiptIn(product);
        //检查有没有出库单
        checkReceiptOut(product);
        //检查有没有库存调整库单
        checkReceiptSet(product);
        //检查有没有调拨库单
        checkReceiptMove(product);
        product.setState(entity.getState());
        mapper.updateByPrimaryKeySelective(product);
        return entity;
    }

    /**
     * 分页查询
     *
     * @param params 条件包装
     * @return Product
     */
    public List<Product> getPages(PageParams<Product> params) {
        PageHelper.startPage(params.getCurrentPage(), params.getPerPageTotal());
        return mapper.getPages(params.getParams());
    }

    /**
     * 查看
     *
     * @param id id
     * @return 产品
     */
    public Product view(String id) {
        return mapper.selectByPrimaryKey(id);
    }

    public List<CategotryProduct> getProductByTypeAndCategory(PageParams<Product> params) {
        PageHelper.startPage(params.getCurrentPage(), params.getPerPageTotal());
        List<CategotryProduct> pageList = mapper.getProductByTypeAndCategory(params.getParams());
        for (CategotryProduct categotryProduct : pageList) {
            categotryProduct.setCategoryName(categoryMapper.selectByPrimaryKey(params.getParams().getCategoryId()).getName());
            categotryProduct.setTypeCode(productTypeMapper.selectByPrimaryKey(categotryProduct.getType()).getCode());
            categotryProduct.setTypeName(productTypeMapper.selectByPrimaryKey(categotryProduct.getType()).getName());
        }
        return pageList;
    }

    public void importProduct(MultipartFile file, String orgId, String userId) throws Exception {
        ImportParams importParams = new ImportParams();
        importParams.setTitleRows(0);
        importParams.setHeadRows(1);
        // 需要验证
        importParams.setNeedVerfiy(true);
        ExcelImportResult<ProductImport> result = ExcelImportUtil.importExcelMore(file.getInputStream(), ProductImport.class,
                importParams);
        //校验是否有错误
        List<ProductImport> failList = result.getFailList();
        for (ProductImport productImport : failList) {
            if (ObjectUtil.checkObjAllFieldsIsNull(productImport)) {
                failList.remove(productImport);
            }
        }
        if (failList.size() > 0) {
            throw new LogicException("第" + (failList.get(0).getRowNum() + 1) + "行错误：" + failList.get(0).getErrorMsg());
        }
        List<ProductImport> list = result.getList();
        if (list.size() == 0) {
            throw new LogicException("请检查导入文件内容");
        }
        insertImport(list, orgId, userId);
    }

    private void insertImport(List<ProductImport> list, String orgId, String userId) throws InterruptedException {
        for (ProductImport productImport : list) {
            Product product = new Product();
            ProductType type = productTypeMapper.getTypeByName(productImport.getTypeName(), orgId);
            if (null == type) {
                throw new LogicException(productImport.getName() + "物品分类不存在");
            }
            product.setType(type.getId());
            product.setOrgId(orgId);
            product.setCuser(userId);
            product.setEuser(userId);
            product.setEtime(DateUtil.now());
            product.setCtime(DateUtil.now());
            product.setTemporary(2);
            if (StrUtil.isBlank(productImport.getForbidden()) || productImport.getForbidden().equals("N")) {
                product.setState(1);
            } else if (productImport.getForbidden().equals("Y")) {
                product.setState(2);
            } else {
                throw new LogicException("是否禁用格式为Y/N,（Y表示禁用，N表示不禁用，不填默认为N不禁用）");
            }
            product.setName(productImport.getName());
            product.setCode(productImport.getCode());
            product.setBarCode(productImport.getBarCode());
            product.setModel(productImport.getModel());
            product.setPrice(productImport.getPrice());
            product.setSafeMax(productImport.getSafeMax());
            product.setSafeMin(productImport.getSafeMin());
            product.setUnit(productImport.getUnit());
            add(product);
        }
    }

    public List<Product> getAll(Product params) {
        Example example = new Example(Product.class);
        // 条件查询
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orgId", params.getOrgId());
        if (StrUtil.isNotEmpty(params.getType())) {
            criteria.andEqualTo("type", params.getType());
        }
        criteria.andEqualTo("temporary", 2);
        criteria.andNotEqualTo("state", 3);
        example.orderBy("ctime").desc();
//        List<Product> productList = mapper.selectByExample(example);
        List<Product> productList = mapper.getPages(params);
        for (Product product : productList) {
            product.setTypeName(productTypeMapper.selectByPrimaryKey(product.getType()).getName());
            product.setTypeCode(productTypeMapper.selectByPrimaryKey(product.getType()).getCode());
            if (product.getState() == 1) {
                product.setState1("可用");
            } else {
                product.setState1("禁用");
            }
            product.setCuserName(userManagementMapper.selectByPrimaryKey(product.getCuser()).getName());
        }
        return productList;
//        return mapper.getPages(params);
    }

    public List<ProductStatistics> statistics(PageParams<StatisticsParams> params) {
        UserManagement user = userManagementMapper.selectByPrimaryKey(params.getParams().getUserId());
        if (user.getDataIsAll() == 1) {
            params.getParams().setIsAdmin(1);
        } else {
            params.getParams().setIsAdmin(2);
        }
        PageHelper.startPage(params.getCurrentPage(), params.getPerPageTotal());
        List<ProductStatistics> products = mapper.getStatistics(params.getParams());
        for (ProductStatistics product : products) {
            params.getParams().setCategoryId(product.getCategoryId());
            params.getParams().setProductId(product.getId());
            ProductStatistics stain = mapper.getInStatistics(params.getParams());
            ProductStatistics staout = mapper.getOutStatistics(params.getParams());
            ProductStatistics staRest = mapper.getRestStatistics(params.getParams());
            DecimalFormat df = new DecimalFormat("0.00");//设置保留位数
            if (stain == null) {
                product.setInNum(0);
                product.setInPrice("0.00");
                product.setInTotalPrice("0.00");
            } else {
                product.setInNum(stain.getInNum());
                product.setInTotalPrice(df.format(Float.parseFloat(stain.getInTotalPrice())));
                product.setInPrice(df.format(Float.parseFloat(stain.getInTotalPrice()) / stain.getInNum()));
            }
            if (staout == null) {
                product.setOutNum(0);
                product.setOutPrice("0.00");
                product.setOutTotalPrice("0.00");
            } else {
                product.setOutNum(staout.getOutNum());
                product.setOutTotalPrice(df.format(Float.parseFloat(staout.getOutTotalPrice())));
                product.setOutPrice(df.format(Float.parseFloat(staout.getOutTotalPrice()) / staout.getOutNum()));
            }
            if (staRest == null) {
                product.setTotalNum(0);
                product.setTotalPrice("0.00");
                product.setPrice("0.00");
            } else {
                product.setTotalNum(staRest.getTotalNum());
                product.setPrice(df.format(Float.parseFloat(staRest.getPrice())));
                product.setTotalPrice(df.format(Float.parseFloat(staRest.getTotalPrice())));
            }
        }
        return products;
    }

    public List<Product> getProductByCategory(IdParams params) {
        List<Product> products = new ArrayList<>();
        Example example = new Example(CategoryProduct.class);
        // 条件查询
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("categoryId", params.getId());
        List<CategoryProduct> productList = categoryProductMapper.selectByExample(example);
        productList.forEach(categoryProduct -> {
            Product product = mapper.selectByPrimaryKey(categoryProduct.getProductId());
            products.add(product);
        });
        return products;
    }

    public List<Qwert> statisticsDetail(PageParams<StatisticsParams> params) {
        if (StrUtil.isBlank(params.getParams().getCategoryId())) {
            throw new LogicException("请选择仓库");
        }
        if (StrUtil.isBlank(params.getParams().getProductId())) {
            throw new LogicException("请选择物品");
        }
        PageHelper.startPage(params.getCurrentPage(), params.getPerPageTotal());
        List<Qwert> result = qwertMapper.qwer(params.getParams());
        result.forEach(qwert -> {
            if (StrUtil.isEmpty(qwert.getNumber())) {
                qwert.setType("平库");
                if (qwert.getNum() < 0) {
                    qwert.setOutNum(-1 * qwert.getNum());
                    qwert.setOutPrice(qwert.getPrice());
                    qwert.setOutTotalPrice(qwert.getTotalPrice().replaceAll("-", ""));
                } else {
                    qwert.setInNum(qwert.getNum());
                    qwert.setInPrice(qwert.getPrice());
                    qwert.setInTotalPrice(qwert.getTotalPrice());
                }
            }
            if (qwert.getNumber().contains("PK")) {
                qwert.setType("盘亏出库");
                qwert.setOutNum(qwert.getNum());
                qwert.setOutPrice(qwert.getPrice());
                qwert.setOutTotalPrice(qwert.getTotalPrice());
            } else if (qwert.getNumber().contains("CK")) {
                qwert.setType("耗材出库");
                qwert.setOutNum(qwert.getNum());
                qwert.setOutPrice(qwert.getPrice());
                qwert.setOutTotalPrice(qwert.getTotalPrice());
            } else if (qwert.getNumber().contains("RK")) {
                qwert.setType("耗材入库");
                qwert.setInNum(qwert.getNum());
                qwert.setInPrice(qwert.getPrice());
                qwert.setInTotalPrice(qwert.getTotalPrice());
            } else if (qwert.getNumber().contains("TZ")) {
                qwert.setType("库存调整");
                if (qwert.getNum() < 0) {
                    qwert.setOutNum(-1 * qwert.getNum());
                    qwert.setOutPrice(qwert.getPrice());
                    qwert.setOutTotalPrice(qwert.getTotalPrice().replaceAll("-", ""));
                } else {
                    qwert.setInNum(qwert.getNum());
                    qwert.setInPrice(qwert.getPrice());
                    qwert.setInTotalPrice(qwert.getTotalPrice());
                }
            } else if (qwert.getNumber().contains("PY")) {
                qwert.setType("盘盈入库");
                qwert.setInNum(qwert.getNum());
                qwert.setInPrice(qwert.getPrice());
                qwert.setInTotalPrice(qwert.getTotalPrice());
            } else if (qwert.getNumber().contains("DB")) {
                if (params.getParams().getCategoryId().equals(qwert.getCategoryId1())) {
                    qwert.setType("耗材调出");
                    qwert.setOutNum(qwert.getNum());
                    qwert.setOutPrice(qwert.getPrice());
                    qwert.setOutTotalPrice(qwert.getTotalPrice());
                } else if (params.getParams().getCategoryId().equals(qwert.getCategoryId())) {
                    qwert.setType("耗材调入");
                    qwert.setInNum(qwert.getNum());
                    qwert.setInPrice(qwert.getPrice());
                    qwert.setInTotalPrice(qwert.getTotalPrice());
                }
            }
            qwert.setCuserName(userManagementMapper.selectByPrimaryKey(qwert.getCuser()).getName());
        });
        return result;
    }


    public List<ProductStatistics> export(StatisticsParams params) {
        UserManagement user = userManagementMapper.selectByPrimaryKey(params.getUserId());
        if (user.getDataIsAll() == 1) {
            params.setIsAdmin(1);
        } else {
            params.setIsAdmin(2);
        }
        List<ProductStatistics> products = mapper.getStatistics(params);
        for (ProductStatistics product : products) {
            params.setCategoryId(product.getCategoryId());
            params.setProductId(product.getId());
            ProductStatistics stain = mapper.getInStatistics(params);
            ProductStatistics staout = mapper.getOutStatistics(params);
            ProductStatistics staRest = mapper.getRestStatistics(params);
            DecimalFormat df = new DecimalFormat("0.00");//设置保留位数
            if (stain == null) {
                product.setInNum(0);
                product.setInPrice("0.00");
                product.setInTotalPrice("0.00");
            } else {
                product.setInNum(stain.getInNum());
                product.setInTotalPrice(df.format(Float.parseFloat(stain.getInTotalPrice())));
                product.setInPrice(df.format(Float.parseFloat(stain.getInTotalPrice()) / stain.getInNum()));
            }
            if (staout == null) {
                product.setOutNum(0);
                product.setOutPrice("0.00");
                product.setOutTotalPrice("0.00");
            } else {
                product.setOutNum(staout.getOutNum());
                product.setOutTotalPrice(df.format(Float.parseFloat(staout.getOutTotalPrice())));
                product.setOutPrice(df.format(Float.parseFloat(staout.getOutTotalPrice()) / staout.getOutNum()));
            }
            if (staRest == null) {
                product.setTotalNum(0);
                product.setTotalPrice("0.00");
                product.setPrice("0.00");
            } else {
                product.setTotalNum(staRest.getTotalNum());
                product.setPrice(df.format(Float.parseFloat(staRest.getPrice())));
                product.setTotalPrice(df.format(Float.parseFloat(staRest.getTotalPrice())));
            }
        }
        return products;
    }

    public List<Qwert> exportDetail(StatisticsParams params) {
        List<Qwert> result = qwertMapper.qwer(params);
        result.forEach(qwert -> {
            if (StrUtil.isEmpty(qwert.getNumber())) {
                qwert.setType("平库");
                if (qwert.getNum() < 0) {
                    qwert.setOutNum(-1 * qwert.getNum());
                    qwert.setOutPrice(qwert.getPrice());
                    qwert.setOutTotalPrice(qwert.getTotalPrice().replaceAll("-", ""));
                } else {
                    qwert.setInNum(qwert.getNum());
                    qwert.setInPrice(qwert.getPrice());
                    qwert.setInTotalPrice(qwert.getTotalPrice());
                }
            }
            if (qwert.getNumber().contains("PK")) {
                qwert.setType("盘亏出库");
                qwert.setOutNum(qwert.getNum());
                qwert.setOutPrice(qwert.getPrice());
                qwert.setOutTotalPrice(qwert.getTotalPrice());
            } else if (qwert.getNumber().contains("CK")) {
                qwert.setType("耗材出库");
                qwert.setOutNum(qwert.getNum());
                qwert.setOutPrice(qwert.getPrice());
                qwert.setOutTotalPrice(qwert.getTotalPrice());
            } else if (qwert.getNumber().contains("RK")) {
                qwert.setType("耗材入库");
                qwert.setInNum(qwert.getNum());
                qwert.setInPrice(qwert.getPrice());
                qwert.setInTotalPrice(qwert.getTotalPrice());
            } else if (qwert.getNumber().contains("TZ")) {
                qwert.setType("库存调整");
                if (qwert.getNum() < 0) {
                    qwert.setOutNum(-1 * qwert.getNum());
                    qwert.setOutPrice(qwert.getPrice());
                    qwert.setOutTotalPrice(qwert.getTotalPrice().replaceAll("-", ""));
                } else {
                    qwert.setInNum(qwert.getNum());
                    qwert.setInPrice(qwert.getPrice());
                    qwert.setInTotalPrice(qwert.getTotalPrice());
                }
            } else if (qwert.getNumber().contains("PY")) {
                qwert.setType("盘盈入库");
                qwert.setInNum(qwert.getNum());
                qwert.setInPrice(qwert.getPrice());
                qwert.setInTotalPrice(qwert.getTotalPrice());
            } else if (qwert.getNumber().contains("DB")) {
                if (params.getCategoryId().equals(qwert.getCategoryId1())) {
                    qwert.setType("耗材调出");
                    qwert.setOutNum(qwert.getNum());
                    qwert.setOutPrice(qwert.getPrice());
                    qwert.setOutTotalPrice(qwert.getTotalPrice());
                } else if (params.getCategoryId().equals(qwert.getCategoryId())) {
                    qwert.setType("耗材调入");
                    qwert.setInNum(qwert.getNum());
                    qwert.setInPrice(qwert.getPrice());
                    qwert.setInTotalPrice(qwert.getTotalPrice());
                }
            }
            qwert.setCuserName(userManagementMapper.selectByPrimaryKey(qwert.getCuser()).getName());
        });
        return result;
    }

    public List<Product> getPagesIn(PageParams<Product> params) {
        PageHelper.startPage(params.getCurrentPage(), params.getPerPageTotal());
        return mapper.getPagesIn(params.getParams());
    }

    public void productTotalNum(String orgId){
        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orgId", orgId);
        criteria.andNotEqualTo("state", 3);
        int count = mapper.selectCountByExample(example);
        UsageManagement ment = mapper.selUsage(orgId);
        if(ment.getType()!=3 && Integer.valueOf(ment.getNumber())<=count){
            throw new LogicException("已有耗材数量不能超出购买耗材数量");
        }
    }
}
